package com.ecnu.codelearn.conf;

import com.ecnu.codelearn.common.HttpResult;
import com.ecnu.codelearn.common.JsonResult;
import com.ecnu.codelearn.exception.BusinessException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.MessageSource;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.servlet.http.HttpServletRequest;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.List;
import java.util.Set;

/**
 * @Author: 曹培胜
 * @Date: 2021/09/05/17:26
 * @Description:
 */

@Slf4j
@RestControllerAdvice
public class ControllerAdviceProcessor {

    protected final MessageSource messageSource;

    public ControllerAdviceProcessor(MessageSource messageSource) {
        this.messageSource = messageSource;
    }

    @ExceptionHandler(BusinessException.class)
    @ResponseBody
    public HttpResult handleException(HttpServletRequest request, BusinessException ex) {
        return HttpResult.error(ex.getMessage());
    }

    @ExceptionHandler(value = BindException.class)
    public JsonResult exceptionHandle(BindException exception) {

        BindingResult result = exception.getBindingResult();
        StringBuilder errorMsg = new StringBuilder();

        List<FieldError> fieldErrors = result.getFieldErrors();
        fieldErrors.forEach(error -> {
            log.error("field: " + error.getField() + ", msg:" + error.getDefaultMessage());
            errorMsg.append(error.getDefaultMessage()).append("!");
        });
        return JsonResult.fail(errorMsg.toString());
    }

    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public JsonResult MyExceptionHandle(MethodArgumentNotValidException exception) {

        BindingResult result = exception.getBindingResult();
        StringBuilder errorMsg = new StringBuilder();

        List<FieldError> fieldErrors = result.getFieldErrors();
        fieldErrors.forEach(error -> {
            log.error("field: " + error.getField() + ", msg:" + error.getDefaultMessage());
            errorMsg.append(error.getDefaultMessage()).append("!");
        });

        return JsonResult.fail(errorMsg.toString());
    }

    @ExceptionHandler(value = ConstraintViolationException.class)
    public JsonResult MyExceptionHandle(ConstraintViolationException exception) {

        Set<ConstraintViolation<?>> result = exception.getConstraintViolations();
        StringBuilder errorMsg = new StringBuilder();


        result.forEach(error -> {
            log.error("field: " + error.getInvalidValue() + ", msg:" + error.getMessage());
            errorMsg.append(error.getMessage()).append("!");
        });

        return JsonResult.fail(errorMsg.toString());
    }

    // 处理运行时异常
    @ExceptionHandler(RuntimeException.class)
    public JsonResult doHandleRuntimeException(RuntimeException e) {
        log.error(e.getMessage(), e);
        e.printStackTrace();
        return JsonResult.fail(e.getMessage());
    }
}
